
import { BaseViewCmpt } from '../../Frame/Script/Base/baseViewCmpt';
import { App } from '../app';
import { EventName } from '../../Frame/Script/const/eventName';
import { Block } from '../item/Block';
import { ResLoadHelper } from '../../Frame/Script/resLoadHelper';
import { NextBlock } from '../item/NextBlock';
import CommonUtil from '../../Frame/Script/CommonUtil';
import { MsgGamePlaying } from '../network/net_proto/protocols/game/MsgGamePlaying';
import { MsgClearLine } from '../network/net_proto/protocols/game/MsgClearLine';
import { MsgGameOver } from '../network/net_proto/protocols/game/MsgGameOver';
import { ViewName } from '../../Frame/Script/const/viewNameConst';
import { ToolsHelper } from '../../Frame/Script/toolsHelper';
import { AddScore } from '../item/AddScore';
import { MsgSink } from '../network/net_proto/protocols/game/MsgSink';
import { AudioName } from '../../Frame/Script/const/enumConst';
const { ccclass, property } = cc._decorator;

const speedPanelX = [0, 40, 100];
const seatX = {
    2: [-175, -75],
    3: [-230, -130, -30],
    4: [-290, -190, -90, 10]
}
// 2-500 3-580  4-694 
const xialuo_spine_name = ["one", "two", "three", "four"];

@ccclass
export class Model1ViewManager extends BaseViewCmpt {

    private top_bg: cc.Node = null;
    private game_bg: cc.Node = null;
    private grid_par: cc.Node = null;
    private grid_model: cc.Node = null;
    private block_box: cc.Node = null;
    private block_area: cc.Node = null;
    private next_block_area: cc.Node = null;
    private speed_panel: cc.Node = null;
    private seat1: cc.Node = null;
    private seat2: cc.Node = null;
    private seat3: cc.Node = null;
    private seat4: cc.Node = null;
    private total_score_label: cc.Label = null;
    private count_down_label: cc.Label = null;
    private bottomUI: cc.Node = null;
    private tween_anim: cc.Node = null;


    private anim_fx_alarm: sp.Skeleton = null;
    private anim_fx_warning: sp.Skeleton = null;
    private anim_fx_blast: sp.Skeleton = null;
    private anim_xialuo: sp.Skeleton = null;
    private anim_xiaochu: sp.Skeleton = null;
    private anim_fx_flash: sp.Skeleton = null;
    private anim_gaojixiaochu: sp.Skeleton = null;

    private anim_clear_list: sp.Skeleton[] = [];
    private anim_leidian_list: sp.Skeleton[] = [];

    private mapData: Block[][] = [];
    private nextData: NextBlock[][] = [];
    private oldShape1: number[][] = null;
    private oldShape2: number[][] = null;
    private oldShape3: number[][] = null;
    private oldShape4: number[][] = null;
    private countValue: number = 3;


    protected onLoad(): void {
        super.onLoad();
        this.top_bg = this.viewList.get("content/top/top_bg");
        this.game_bg = this.viewList.get("content/game/game_bg");
        this.grid_par = this.viewList.get("content/game/gridPar");
        this.grid_model = this.viewList.get("content/game/gridPar/img_grid");
        this.block_box = this.viewList.get("content/game/img_block_box");
        this.block_area = this.viewList.get("content/game/blockArea");
        this.next_block_area = this.viewList.get("content/top/top_bg/blockShow/nextBlockArea");
        this.speed_panel = this.viewList.get("content/game/game_bg/speedPanel");
        this.seat1 = this.viewList.get("content/top/seat1");
        this.seat2 = this.viewList.get("content/top/seat2");
        this.seat3 = this.viewList.get("content/top/seat3");
        this.seat4 = this.viewList.get("content/top/seat4");
        this.total_score_label = this.viewList.get("content/top/top_bg/scoreLabel").getComponent(cc.Label);
        this.count_down_label = this.viewList.get("content/game/img_block_box/countDownLabel").getComponent(cc.Label);
        this.bottomUI = this.viewList.get("content/bottom");
        this.tween_anim = this.viewList.get("content/game/tween_anim");

        this.anim_fx_alarm = this.viewList.get("content/animaMask/anim_fx_alarm").getComponent(sp.Skeleton);
        this.anim_fx_warning = this.viewList.get("content/game/anim_fx_warning").getComponent(sp.Skeleton);
        this.anim_fx_blast = this.viewList.get("content/game/anim_fx_blast").getComponent(sp.Skeleton);
        this.anim_xialuo = this.viewList.get("content/game/anim_xialuo").getComponent(sp.Skeleton);
        this.anim_xiaochu = this.viewList.get("content/game/anim_xiaochu").getComponent(sp.Skeleton);
        this.anim_fx_flash = this.viewList.get("content/game/anim_fx_flash").getComponent(sp.Skeleton);
        this.anim_gaojixiaochu = this.viewList.get("content/game/anim_gaojixiaochu").getComponent(sp.Skeleton);

        App.event.on(EventName.Game.GAME_PLAYING, this.onUpdateViewContent, this);
        App.event.on(EventName.Game.CLEAR_LINE, this.onClearLine, this);
        App.event.on(EventName.Game.SINK, this.onSink, this);
        App.event.on(EventName.Game.GAME_OVER, this.onGameOver, this);
    }

    protected start(): void {
        App.gameData.isGameStart = false;
        App.gameData.isGameOver = false;
        App.gameData.model1_clearLineCount = 0;
        App.gameData.model1_totalScore = 0;
        App.gameData.model1_map = null;
        App.gameData.user_score_map = { 1: 0, 2: 0, 3: 0, 4: 0 };
        this.bottomUI.active = App.user.seatId !== 0;
        this.initViewSize();
        this.initSeatShow();
        this.initGameArea();
        this.initNextArea();
        this.updateTotalScore(0);
        this.initSkeletonAnim();
        this.playCountDownAnim();
    }

    private playCountDownAnim() {
        this.schedule(() => {
            this.countValue -= 1;
            if (this.countValue === -1) {
                App.audio.playEffect(AudioName.game_end_count_down);
                this.count_down_label.node.active = false;
                App.gameData.isGameStart = true;
            } else {
                App.audio.playEffect(AudioName.game_start_count_down);
                this.count_down_label.string = this.countValue.toString();
            }
        }, 1, 4);
    }

    private onUpdateViewContent(data: MsgGamePlaying) {
        // console.log("MsgGamePlaying=>", data);
        App.gameData.model1_map = data.selfMap;
        let seatId = App.user.seatId > 0 ? App.user.seatId : 1;
        this.updateGameArea(data.selfMap);
        this.updateNextArea(data["nextShape_" + seatId]);
        if (data.bornRowCol) {
            console.log("--playing--", data);
            let shape_wid = this["oldShape" + seatId][0].length;
            let shape_hei = this["oldShape" + seatId].length;
            this.controlDropAnim(true, shape_wid, shape_hei, data.bornRowCol);
        } else {
            this.oldShape1 = data.currentShape_1;
            this.oldShape2 = data.currentShape_2;
            this.oldShape3 = data.currentShape_3;
            this.oldShape4 = data.currentShape_4;
        }
    }

    private onClearLine(data: MsgClearLine) {
        console.log("MsgClearLine=>", data);
        /** 添加消除动画  加分 */
        this.updateTotalScore(data.totalScore);
        App.gameData.model1_totalScore = data.totalScore;
        for (let i = 0; i < 4; i++) {
            let seat_id = i + 1;
            App.gameData.user_score_map[seat_id] = data["score_" + seat_id];
            this.updateSeatScore(seat_id, data["score_" + seat_id]);
        }
        App.gameData.model1_clearLineCount += data.clearLine.length;
        let lines: number[] = ToolsHelper.cloneObject(data.clearLine);
        if (lines.length > 2) lines.sort((a, b) => { return a - b });
        this.playAddScoreAnim(data.addScore, lines[0]);
        this.playClearLineAnim(lines);
        App.audio.playEffect(AudioName.clear_row);
    }

    private onSink(data: MsgSink) {
        console.log("MsgSink=>", data);
        this.updateGameArea(data.selfMap);
    }

    private playClearLineAnim(clearLine: number[]) {
        console.log("playClearLineAnim->", clearLine);
        this.controlClearAnim(true, clearLine);
        this.controlGaojiAnim(true);
    }

    private async playAddScoreAnim(addScore: number, addCol: number) {
        let gridSize = App.gameData.GridSize;
        let offsetY = (-addCol + 2) * gridSize;
        let add_pre: cc.Prefab = await ResLoadHelper.loadAssetSync("prefabs/item/addScore", cc.Prefab) as cc.Prefab;
        let add_node: cc.Node = cc.instantiate(add_pre);
        add_node.setPosition(cc.v3(0, offsetY, 0));
        add_node.parent = this.tween_anim;
        add_node.getComponent(AddScore).showAddAnim(addScore);
    }

    private onGameOver(data: MsgGameOver) {
        console.log("MsgGameOver=>", data);
        App.audio.playEffect(AudioName.game_over);
        App.gameData.isGameOver = data.isOver;
        let seats = App.gameData.getGameSeats();
        for (let i = 0; i < seats.length; i++) {
            let seat_data = seats[i];
            if (seat_data.user) {
                seat_data.user.isReady = false;
            }
        }
        if (data.isOver) {
            this.onClick_closeBtn();
            App.view.openView(ViewName.Single.eModel1OverView);
        }
    }

    private async initGameArea() {
        let gridSize = App.gameData.GridSize;
        let tabular: number[] = App.gameData["TEAMWORk_" + App.gameData.getPeopleNum()];
        const [total_row, total_col] = tabular;
        let block_pre = await ResLoadHelper.loadAssetSync("prefabs/item/block", cc.Prefab) as cc.Prefab;
        let block: cc.Node = null;
        let blockCom: Block = null;
        for (let row = 0, y = -gridSize; row < total_row; row++, y -= gridSize) {
            this.mapData[row] = []
            for (let col = 0, x = 0; col < total_col; col++, x += gridSize) {
                block = cc.instantiate(block_pre);
                block.setContentSize(cc.size(36, 36));
                block.setPosition(cc.v3(x, y, 0));
                blockCom = block.getComponent(Block);
                blockCom.initBlock(false);
                block.parent = this.block_area;
                this.mapData[row][col] = blockCom;
            }
        }
    }

    private async initNextArea() {
        let offset = 8;
        let next_block_pre = await ResLoadHelper.loadAssetSync("prefabs/item/nextBlock", cc.Prefab) as cc.Prefab;
        let next_block: cc.Node = null;
        let next_blockCom: NextBlock = null;
        for (let row = 0, y = 0; row < 4; row++, y -= 11) {
            this.nextData[row] = [];
            for (let col = 0, x = 0; col < 4; col++, x += 11) {
                next_block = cc.instantiate(next_block_pre);
                next_block.setContentSize(cc.size(10, 10));
                next_block.setPosition(cc.v3(x + offset, y - offset, 0));
                next_blockCom = next_block.getComponent(NextBlock);
                next_blockCom.initBlock(false);
                next_block.parent = this.next_block_area;
                this.nextData[row][col] = next_blockCom;
            }
        }
    }

    private updateGameArea(map: number[][]) {
        let value = 0;
        let color_value = 1;
        let blockCom: Block = null;
        for (let i = 0; i < this.mapData.length; i++) {
            for (let j = 0; j < this.mapData[0].length; j++) {
                if (!map[i + 3]) return;
                value = map[i + 3][j];
                color_value = (value / 10) | 0;
                blockCom = this.mapData[i][j];
                blockCom.setBlock(color_value, value > 0);
            }
        }
    }

    private updateNextArea(shape: number[][]) {
        let value = 0;
        let color_value = 1;
        let nextBlock: NextBlock = null;
        for (let i = 0; i < this.nextData.length; i++) {
            for (let j = 0; j < this.nextData[i].length; j++) {
                nextBlock = this.nextData[i][j];
                if (shape[i] && shape[i][j] && shape[i][j] > 0) {
                    value = shape[i][j];
                    color_value = (value / 10) | 0;
                } else {
                    value = 0;
                }
                nextBlock.setBlock(color_value, value > 0);
            }
        }
    }

    /** 初始化游戏的尺寸 */
    private initViewSize() {
        let people_num = App.gameData.getPeopleNum();
        let game_size: number[] = App.gameData["TEAMWORk_" + people_num];
        let box_size = cc.size(game_size[1] * App.gameData.GridSize, game_size[0] * App.gameData.GridSize);
        let grid_total = game_size[0] * game_size[1];
        this.block_box.setContentSize(box_size);
        this.grid_par.setContentSize(box_size);
        this.block_area.setContentSize(box_size);
        this.block_area.setPosition(cc.v3(-box_size.width / 2, box_size.height / 2, 0));
        let add_wid = people_num <= 2 ? 50 : 10;
        let bg_size = this.game_bg.getContentSize();
        this.game_bg.setContentSize(cc.size(box_size.width + add_wid, bg_size.height));
        let top_size = this.top_bg.getContentSize();
        this.top_bg.setContentSize(cc.size(box_size.width + add_wid, top_size.height));
        let speedX = speedPanelX[people_num - 2];
        this.speed_panel.position.add(cc.v3(speedX, 0, 0));
        for (let i = 0; i < grid_total; i++) {
            if (i === 0) {
                this.grid_model.name = "grid_" + i;
            } else {
                let grid = cc.instantiate(this.grid_model);
                grid.name = "grid_" + i;
                grid.parent = this.grid_par;
            }
        }
    }

    /** 初始化座位显示 */
    private initSeatShow() {
        let seats = App.gameData.getGameSeats();
        let people_num = App.gameData.getPeopleNum();
        let seatPosX: number[] = ToolsHelper.cloneObject(seatX[people_num]);
        for (let i = 0; i < 4; i++) {
            let seat_data = seats[i];
            let seatId = i + 1;
            this.updateSeatScore(seatId, 0);
            let p: cc.Node = this["seat" + seatId];
            let nameLabel = p.getChildByName("nameLabel").getComponent(cc.Label);
            let head_spr = p.getChildByName("mask").children[0].getComponent(cc.Sprite);
            let head_default = p.getChildByName("img_default_head");
            if (seat_data.user) {
                let posX = seatPosX.shift();
                p.setPosition(cc.v3(posX, 0, 0));
                p.active = true;
                nameLabel.string = seat_data.user.name;
                head_default.active = false;
                head_spr.node.active = true;
                ResLoadHelper.loadAssetAsync(seat_data.user.icon, cc.SpriteFrame, (frame: cc.SpriteFrame) => {
                    if (frame) {
                        head_spr.spriteFrame = frame;
                    } else {
                        head_default.active = true;
                        head_spr.node.active = false;
                    }
                }, true)
            } else {
                p.active = false;
                nameLabel.string = "";
            }
        }
    }

    private async initSkeletonAnim() {
        this.controlFxAnim(false);
        this.controlDropAnim(false);
        await this.initClearAnimList();
        this.controlClearAnim(false);
        this.controlGaojiAnim(false);

        this.anim_fx_warning.node.active = false;
    }

    /** 更新对应座位上的分数显示 */
    private updateSeatScore(seatId: number, value: number) {
        let seatNode = this["seat" + seatId];
        let seat_score_label: cc.Label = seatNode.getChildByName("scoreLabel").getComponent(cc.Label);
        seat_score_label.string = "" + value;
    }

    /** 更新总分数显示 */
    private updateTotalScore(value: number) {
        this.total_score_label.string = "" + value;
    }

    /** 控制全屏闪缩的spine动画 */
    private controlFxAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_fx_alarm.node.active = true;
            this.anim_fx_alarm.setAnimation(0, "animation", true);
        } else {
            this.anim_fx_alarm.node.active = false;
            this.anim_fx_alarm.clearTracks();
        }
    }

    /** 控制快速落定动画效果 */
    private controlDropAnim(isPlay: boolean, widCount?: number, heiCount?: number, bornRowCol?: number[]) {
        if (isPlay) {
            if (widCount !== undefined) {
                let idx = widCount - 1;
                let spine_name = xialuo_spine_name[idx];
                let ranType = (Math.random() * 3 + 1) | 0;
                let blast_name = "blast0" + ranType;
                let people_num = App.gameData.getPeopleNum();
                let game_size: number[] = App.gameData["TEAMWORk_" + people_num];
                let middle_col = game_size[1] / 2;
                let offset_x = (bornRowCol[1] + widCount / 2 - middle_col) * App.gameData.GridSize;
                let offset_y = (10.5 - bornRowCol[0] - heiCount / 2) * App.gameData.GridSize;
                this.anim_xialuo.node.setPosition(cc.v3(offset_x, offset_y, 0));
                this.anim_fx_blast.node.setPosition(cc.v3(offset_x, offset_y, 0));
                this.anim_xialuo.node.active = offset_y < this.block_box.height / 2;
                this.anim_fx_blast.node.active = offset_y < this.block_box.height / 2;
                this.anim_xialuo.setAnimation(0, spine_name, false);
                this.anim_fx_blast.setAnimation(0, blast_name, false);
            }
        } else {
            this.anim_xialuo.node.active = false;
            this.anim_fx_blast.node.active = false;
        }
    }

    /** 消除动画最多可以是四个，最少一个，所以直接创建四个出来，进行动态控制 */
    private initClearAnimList() {
        for (let i = 0; i < 4; i++) {
            let newClearNode = cc.instantiate(this.anim_xiaochu.node);
            newClearNode.parent = this.anim_xiaochu.node.parent;
            newClearNode.active = false;
            let newClearSpine = newClearNode.getComponent(sp.Skeleton);
            newClearSpine.premultipliedAlpha = false;
            this.anim_clear_list.push(newClearSpine);

            let newLeidianNode = cc.instantiate(this.anim_fx_flash.node);
            newLeidianNode.parent = this.anim_fx_flash.node.parent;
            newLeidianNode.active = false;
            let newLeidianSpine = newLeidianNode.getComponent(sp.Skeleton);
            newLeidianSpine.premultipliedAlpha = false;
            this.anim_leidian_list.push(newLeidianSpine);
        }
    }

    /** 消除动画控制逻辑 */
    private controlClearAnim(isPlay: boolean, clearLine?: number[]) {
        this.anim_xiaochu.node.active = false;
        this.anim_clear_list.forEach(e => e.node.active = false);
        this.anim_leidian_list.forEach(e => e.node.active = false);
        if (isPlay) {
            let people_num = App.gameData.getPeopleNum();
            let clear_anim_name = people_num + "ren";
            let leidian_anim_name = people_num + "ren_line1";
            if (clearLine) {
                clearLine.forEach((rowvalue, index) => {
                    let clearSpine = this.anim_clear_list[index];
                    let leidianSpine = this.anim_leidian_list[index];
                    let offset_y = (10.5 - rowvalue + 1) * App.gameData.GridSize;
                    clearSpine.node.setPosition(cc.v3(0, offset_y, 0));
                    leidianSpine.node.setPosition(cc.v3(0, offset_y, 0));
                    clearSpine.node.active = true;
                    leidianSpine.node.active = true;
                    clearSpine.setAnimation(0, clear_anim_name, false);
                    leidianSpine.setAnimation(0, leidian_anim_name, false);
                })
            }
        }
    }

    /** 消除同时的边框动画 */
    private controlGaojiAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_gaojixiaochu.node.active = true;
            let people_num = App.gameData.getPeopleNum();
            let anim_name = people_num + "ren";
            this.anim_gaojixiaochu.setAnimation(0, anim_name, false);
        } else {
            this.anim_gaojixiaochu.node.active = false;
        }
    }

    protected onDestroy(): void {
        App.event.off(EventName.Game.GAME_PLAYING, this);
        App.event.off(EventName.Game.CLEAR_LINE, this);
        App.event.off(EventName.Game.SINK, this);
        App.event.off(EventName.Game.GAME_OVER, this);
    }
}


